import { ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus, Logger } from "@nestjs/common";
import { Request, Response } from "express";

/**
 * 全局异常过滤器
 */
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
    // exception 当前正在处理的异常对象,例如 BadRequestException, NotFoundException 等
    // ArgumentsHost 对象包含了异常发生时的所有上下文信息。它是一个包含原始函数调用参数的包装器, 是传递给原始处理程序的参数的一个包装(Response/Request)的引用
    catch(exception: HttpException, host: ArgumentsHost) {
        console.log('进入全局异常过滤器...', exception);
        const ctx = host.switchToHttp(); // 获取请求上下文,因为 NestJS 支持多种传输层（如 WebSocket、GraphQL 等），而不仅仅限于 HTTP。通过调用 switchToHttp()，你可以确保获得的是与 HTTP 请求相关的上下文
        const response = ctx.getResponse<Response>();
        const request = ctx.getRequest<Request>();
        // const status = exception.getStatus(); // 获取异常状态码
        // data: (exception as any).response.message || exception.message

        // HttpException 属于基础异常类，可自定义内容
        // 如果是自定义的异常类则抛出自定义的status 
        // 否则就是内置HTTP异常类，然后抛出其对应的内置Status内容
        const status =
            exception instanceof HttpException
                ? exception.getStatus()
                : HttpStatus.INTERNAL_SERVER_ERROR;

        // 抛出错误信息
        const message =
            (exception as any).response.message || exception.message

        let msgLog = {
            statusCode: status, // 系统错误状态
            timestamp: new Date().toISOString(), // 错误日期
            path: request.url, // 错误路由
            message: '请求失败',
            data: message // 错误消息内容体(争取和拦截器中定义的响应体一样)
        }

        // 打印错误综合日志
        Logger.error(
            '错误信息',
            JSON.stringify(msgLog),
            'HttpExceptionFilter',
        );

        // 返回错误信息
        response
            .status(status)
            .json(msgLog);
    }

}
